动态规划——基本思想
动态规划的特点
- 把原始问题划分为一系列子问题
- 求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时到时直接存取,不重复计算,节省计算时间
- 自底向上地计算
使用范围
- 一类优化问题:可分为多个相关子问题,子问题的解被重复使用
使用动态规划的条件
- 优化子结构
- 当一个问题的优化解包含了子问题的优化解时,这个问题具有优化子结构。
- 缩小子问题集合,只需那些优化问题中包含的子问题,降低实现复杂性。
- 优化子结构使得我们能自下向上地完成求解过程
- 重叠子问题
- 在问题的求解过程中,很多子问题的解将被多次使用
设计步骤
- 分析优化解的结构
- 递归地定义最优解的代价
- 自底向上地计算优化解的代价保存之,并获取构造最优解的信息
- 根据构造最优解的信息构造优化解
优化子结构的分类
- 编号动态规划:输入为 x1,x2,…,xn ,子问题是 x1,x2,…,xi ,子问题复杂性为 O(n) (最大不下降子序列问题)
- 划分动态规划:输入为 x1,x2,…,xn ,子问题为 xi,xi+1,…,xj ,子问题复杂性是 O(n2) (矩阵链乘问题)
- 数轴动态规划:输入为 x1,x2,…,xn 和数字C,子问题为 x1,x2,…,xi , K(K≤C) ,子问题复杂性 O(nC) (0-1背包问题)
- 前缀动态规划:输入为 x1,x2,…,xn 和 y1,y2,…,ym ,子问题为 x1,x2,…,xi 和 y1,y2,…,yj ,子问题复杂性是 O(mn) (最长公共子序列问题)
- 树形动态规划:输入是树,其子问题为子树,子问题复杂性是子树的个数。(树中独立集合问题)